/* vcc/plugins.c 
 * 
 * This file is part of vcc. 
 * 
 * vcc is free software: you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version. 
 * 
 * vcc is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 * GNU General Public License for more details. 
 * 
 * You should have received a copy of the GNU General Public License 
 * along with vcc. If not, see <https://www.gnu.org/licenses/>
 */ 




#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>
#include <signal.h>

#include <klist.h>
#include <vcc/vcc.h>
#include <vcc/plugin.h>
#include <vcc/version.h>
#include <vcc/pretty.h>
#include <vcc/interfaces.h>


extern struct plugin plg_hello, plg_robot, plg_m4, plg_script, plg_hist, plg_cqd, plg_beep;

struct plugin *plugins[] = {
	&plg_hello, &plg_robot, &plg_m4, &plg_script, &plg_hist, &plg_cqd, &plg_beep, 
	(struct plugin *) NULL
};

int do_cmd_pls(int argc, char **argv) {
	int i;
	struct plugin *p;

	(void) argv;

	if (argc != 1) {
		fprintf(stderr, _("usage: -pls\n"));

		return 1;
	}

	for (i = 0; (p = plugins[i]); i++) 
		pretty_cmd_help(p->name, p->descr);
	
	return 0;
}

struct plugin *find_plg(char *s) {
	int i;
	struct plugin *p;

	for (i = 0; (p = plugins[i]); i++) 
		if (!strcmp(s, p->name)) 
			return p;

	return NULL;
}


int plg_insert(struct plugin *plg) {
	plg->state = PLG_INSERTED;

	return 0;
}

int plg_remove(struct plugin *plg) {
	plg->state = 0;

	return 0;
}


int do_cmd_prem(int argc, char **argv) {
	struct plugin *p;
	char name[MSG_SIZE];
	char *s;

	switch (argc) {
	case 1:
		fprintf(stderr, _("plugin: "));
		scanf("%s", name);

		s = name;
		break;

	case 2:
		s = argv[1];
		break;

	default:
		fprintf(stderr, _("usage: -prem [plugin-name]\n"));
		break;
	}

	if (!(p = find_plg(s))) {
		fprintf(stderr, _("*** plugin not found. \n"));

		return 1;
	}

	if (p->state != PLG_INSERTED) {
		fprintf(stderr, _("*** plugin didn't insert. \n"));

		return 1;
	}

	if (p->exit) 
		p->exit();

	return plg_remove(p);
}


int do_cmd_pins(int argc, char **argv) {
	struct plugin *p;
	char name[MSG_SIZE];
	char *s;

	switch (argc) {
	case 1:
		fprintf(stderr, _("plugin: "));
		scanf("%s", name);

		s = name;

		break;

	case 2:
		s = argv[1];
		break;

	default:
		fprintf(stderr, _("usage: -pins [plugin-name]\n"));
		return 1;
	}

	if (!(p = find_plg(s))) {
		fprintf(stderr, _("*** plugin not found. \n"));

		return 1;
	}
	
	plg_insert(p);
	
	if (p->init) 
		p->init();

	return 0;
}


